vlwkaos' digital garden

GraphQL - validation, execution, introspection

  • 타입 시스템이 필요하다.
  • graphQL API는 최상위 root fields와 resolver의 구현이 필요하다
Query: {
  human(obj, args, context, info) {
    return context.db.loadHumanByID(args.id).then(
      userData => new Human(userData)
    )
  }
}
  • obj 이전 오브젝트 (이전 상태?)
  • args gql쿼리에서 필드에 넘기는 인자
  • context 세션 관련 정보 (로그인된 유저, db access)
  • info A value which holds field-specific information relevant to the current query as well as the schema details, also refer to type GraphQLResolveInfo for more details.

resolver는 비동기임, javascript의 경우 Promise 반환

이제 루트 resolver가 있으므로, 다른 object에 대한 resolver 구현가능

Human: {
  name(obj, args, context, info) {
    return obj.name
  }
}

이런 류의 resolver는 다양한 library를 통해 자동적으로 구현되도록 할 수 있음

🔗 gql lib

Scalar coercion gql 타입 시스템 상에서 enum으로 표현될 수 있지만, 반환시에는 상수값으로

Human: {
  appearsIn(obj) {
    return obj.appearsIn // returns [ 4, 5, 6 ]
  }
}

배열요청은 리스트가 반환되는게 아니고 Promise의 리스트가 반환됨. 병렬적으로 요청이 처리되고 모든 Promise를 기다렸다 반환

Human: {
  starships(obj, args, context, info) {
    return obj.starshipIDs.map(
      id => context.db.loadStarshipByID(id).then(
        shipData => new Starship(shipData)
      )
    )
  }
}

일반적으로 우리는 우리가 사용할 graphql API의 스키마에 대해 알고있지만, 그러지 못할 경우 알 수 있는 방법: __schema를 쿼리로 요청할 수 있다.

{
  __schema {
    types {
      name
    }
  }
}

다음이 introspection용으로 존재하는 것들: __Schema, __Type, __TypeKind, __Field, __InputValue, __EnumValue, __Directive

{
  __type(name: "Droid") {
    name
  }
}

이렇게 오브젝트의 필드에 대한 정보도 가져올 수 있다.

...
fields {
      name
      type {
        name
        kind
      }
    }
...

이렇게 현재 보고하는 타입에 대해 더 상세한 정보를 가져올 수 있다. 예를 들어, type의 name이 STRING 이고 kind는 SCALAR이다.

ofType {
          name
          kind
        }

Referred in

GraphQL - validation, execution, introspection